﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace RPGServer.Contracts.Requests
{
    class RequestMoveObject
    {
        /// <summary>
        /// 处理单位移动请求
        /// </summary>
        public static void Process(RPGPlayer player, byte[] buffer, int length)
        {
            int offset = 2;
            // 单位编号
            uint objectId = IntUtil.UIntFromBuffer(buffer, offset, out offset);
            // 当前地图编号
            ushort curMapId = IntUtil.UShortFromBuffer(buffer, offset, out offset);
            // 当前位置-行
            ushort curPosRow = IntUtil.UShortFromBuffer(buffer, offset, out offset);
            // 当前位置-列
            ushort curPosCol = IntUtil.UShortFromBuffer(buffer, offset, out offset);
            // 目标位置-行
            ushort targetPosRow = IntUtil.UShortFromBuffer(buffer, offset, out offset);
            // 目标位置-列
            ushort targetPosCol = IntUtil.UShortFromBuffer(buffer, offset, out offset);

            Log.Debug("request", "玩家({0})请求移动:[object:{1} map:{2} pos:({3},{4}) targetPos:({5},{6})]",
                player.Id,
                objectId,
                curMapId,
                curPosRow,
                curPosCol,
                targetPosRow,
                targetPosCol);

            // 验证是否允许移动
            bool validateResult = true;
            if (validateResult)
            {
                byte[] data = new byte[255];
                offset = 0;
                // scenario
                IntUtil.ByteToBuffer(RPGNET_SCENARIO.GAME, data, offset, out offset);
                // command
                IntUtil.ByteToBuffer(RPGNET_RESPONSE.MOVEOBJECT, data, offset, out offset);
                // error code
                IntUtil.ByteToBuffer(RPGNET_RESPONSE_ERROR.NOERROR, data, offset, out offset);
                // object id
                IntUtil.UIntToBuffer(objectId, data, offset, out offset);
                // map id
                IntUtil.UShortToBuffer(curMapId, data, offset, out offset);
                // cur pos row
                IntUtil.UShortToBuffer(curPosRow, data, offset, out offset);
                // cur pos col
                IntUtil.UShortToBuffer(curPosCol, data, offset, out offset);
                // target pos row
                IntUtil.UShortToBuffer(targetPosRow, data, offset, out offset);
                // target pos col
                IntUtil.UShortToBuffer(targetPosCol, data, offset, out offset);

                player.Client.SendData(data, offset);

                // 更新玩家的位置，其实不应该在这里更新
                player.CurPosRow = targetPosRow;
                player.CurPosCol = targetPosCol;

                Log.Debug("response", "玩家({0})请求移动成功:[object:{1} map:{2} pos:({3},{4}) targetPos:({5},{6})]", 
                    player.Id,
                    objectId,
                    curMapId,
                    curPosRow,
                    curPosCol,
                    targetPosRow,
                    targetPosCol);

                NotifyMoveObject(curMapId, player, targetPosRow, targetPosCol);
            }
            else
            {
                // 移动失败
                byte[] data = new byte[255];
                offset = 0;
                // scenario
                IntUtil.ByteToBuffer(RPGNET_SCENARIO.GAME, data, offset, out offset);
                // command
                IntUtil.ByteToBuffer(RPGNET_RESPONSE.SWITH_MAP, data, offset, out offset);
                // error code
                IntUtil.ByteToBuffer(RPGNET_RESPONSE_ERROR.UNKNOWN, data, offset, out offset);

                player.Client.SendData(data, offset);
                Log.Error("response", "玩家({0})移动失败:[targetPos:({4},{5})]", 
                    player.Client.GetNetAddress(),
                    targetPosRow,
                    targetPosCol);
            }
        }

        private static void NotifyMoveObject(ushort mapId, RPGPlayer player, ushort targetPosRow, ushort targetPosCol)
        {
            byte[] data = new byte[255];
            int offset = 0;
            // scenario
            IntUtil.ByteToBuffer(RPGNET_SCENARIO.SER_MSG, data, offset, out offset);
            // command
            IntUtil.ByteToBuffer(RPGNET_MESSAGE.MOVE_OBJECT, data, offset, out offset);
            // player id
            IntUtil.UIntToBuffer(player.Id, data, offset, out offset);
            // object id
            IntUtil.UIntToBuffer(player.RoleId, data, offset, out offset);
            // map id
            IntUtil.UShortToBuffer(player.CurMapId, data, offset, out offset);
            // cur pos row
            IntUtil.UShortToBuffer(player.CurPosCol, data, offset, out offset);
            // cur pos col
            IntUtil.UShortToBuffer(player.CurPosRow, data, offset, out offset);
            // target pos row
            IntUtil.UShortToBuffer(targetPosRow, data, offset, out offset);
            // target pos col
            IntUtil.UShortToBuffer(targetPosCol, data, offset, out offset);

            RPGMapPlayerCollection map = CacheData.GetInstance().GetMap(mapId);

            for (int index = 0; index < map.PlayerList.Count; index++)
            {
                RPGPlayer oPlayer = map.PlayerList[index];
                if (oPlayer != null && oPlayer.Id != player.Id)
                {
                    oPlayer.Client.SendData(data, offset);
                }
            }
        }
    }
}
